﻿using HlELock.Core;
using HlELock.Core.Events;
using HlELock.Domain;
using HlELock.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Win32;
using Prism.Commands;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

namespace HlELock.Modules.Hotel.Main.ViewModels
{
    public class BatchNewRoomPageViewModel : DialogViewModelBase
    {
        private readonly HlELockDbContext _dbContext;
        public BatchNewRoomPageViewModel()
        {
            _dbContext = new HlELockDbContext();
            var roomTypes = _dbContext.RoomTypes.OrderBy(o => o.Index).ToList();
            RoomTypes = roomTypes.ToObservableCollection();
        }
        private DelegateCommand _importRoomCommand;
        public DelegateCommand ImportRoomCommand =>
            _importRoomCommand ?? (_importRoomCommand = new DelegateCommand(ExecuteImportRoomCommand));

        void ExecuteImportRoomCommand()
        {
            var openFileDialog = new OpenFileDialog
            {
                Filter = "Excel Files|*.xlsx;*.xls|All Files|*.*",
                Title = "选择 Excel 文件"
            };
            if (openFileDialog.ShowDialog() == true)
            {
                var selectedFile = openFileDialog.FileName;
                EventBus.StartDialogLoading("正在导入");

                try
                {
                    using (var fs = new FileStream(selectedFile, FileMode.Open, FileAccess.Read))
                    {
                        var rooms = fs.ReadExcel<Room>((values, headers, index) =>
                          {
                              //判断模板是否正确
                              var fields = new string[]
                              {
                                "楼栋","楼层","房号","房间类型","特色房型"
                              };
                              var t = fields.Except(headers);
                              if (t.Count() > 0)
                              {
                                  throw new Exception("Excel模板不正确，请下载最新模板");
                              }


                              _ = int.TryParse(values[headers.IndexOf(fields[0])], out int buildNumber);
                              _ = int.TryParse(values[headers.IndexOf(fields[1])], out int floorNumber);

                              var item = new Room()
                              {
                                  BuildingNumber = buildNumber,
                                  FloorNumber = floorNumber,
                                  RoomNumber = values[headers.IndexOf(fields[2])],
                                  RoomType = values[headers.IndexOf(fields[3])],
                                  Feature = values[headers.IndexOf(fields[4])]
                              };
                              return item;
                          });

                        var roomTypes = rooms.Select(s => s.RoomType).Distinct().ToList();
                        //新增房型
                        foreach (var item in roomTypes.Except(RoomTypes.Select(s => s.Name)))
                        {
                            _dbContext.RoomTypes.Add(new RoomType
                            {
                                Name = item,
                                Index = RoomTypes.Count + 1
                            });
                        }

                        //新增房间
                        var dbRooms = _dbContext.Rooms.ToList();
                        foreach (var item in rooms)
                        {
                            var matchRoom = dbRooms.FirstOrDefault(f => f.RoomNumber == item.RoomNumber);
                            if (matchRoom != null)
                            {
                                matchRoom.BuldingName = item.BuldingName;
                                matchRoom.BuildingNumber = item.BuildingNumber;
                                matchRoom.FloorNumber = item.FloorNumber;
                                matchRoom.Feature = item.Feature;
                                matchRoom.RoomType = item.RoomType;
                            }
                            else
                            {
                                _dbContext.Rooms.Add(item);
                            }
                        }
                        _dbContext.SaveChanges();
                    }

                    MessageBox.Show(messageBoxText: "创建成功");
                    EventBus.RefreshRoomList();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(messageBoxText: "导入失败，错误信息：" + ex.Message);
                }
                finally
                {
                    EventBus.StopDialogLoading();
                }

            }
        }

        private DelegateCommand _createRoomCommand;
        public DelegateCommand CreateRoomCommand =>
            _createRoomCommand ?? (_createRoomCommand = new DelegateCommand(ExecuteCreateRoomCommand));


        private RoomType _currentRoomType;
        public RoomType CurrentRoomType
        {
            get { return _currentRoomType; }
            set { SetProperty(ref _currentRoomType, value); }
        }

        void ExecuteCreateRoomCommand()
        {
            if (CurrentRoomType == null)
            {
                MessageBox.Show("请先选择客房类型");
                return;
            }
            if (RoomMin == 0 && RoomMax == 0)
            {
                MessageBox.Show("请填写客户范围");
                return;
            }

            EventBus.StartDialogLoading("创建客户");

            var roomNumbers = CreateNumber(RoomMin, RoomMax, RoomJump, RoomLength, (r, i) => r.RoomNumber += Suffix);

            var floorNumbers = CreateNumber(FloorMin, FloorMax, FloorJump, FloorLength, (r, i) => r.FloorNumber = i);
            if (floorNumbers.Count > 0)
            {
                floorNumbers = floorNumbers.Select(s =>
                {
                    var numbers = roomNumbers.Select(s1 => new Room
                    {
                        FloorNumber = s.FloorNumber,
                        RoomNumber = s.RoomNumber + s1.RoomNumber
                    }).ToList();
                    return numbers;
                }).SelectMany(m => m).ToList();
            }
            else
            {
                floorNumbers = roomNumbers;
            }

            var buildingNumbers = CreateNumber(BuildingMin, BuildingMax, "", BuildingLength, (r, i) => r.BuildingNumber = i);
            if (buildingNumbers.Count > 0)
            {
                buildingNumbers = buildingNumbers.Select(s => new
                {
                    Numbers = floorNumbers.Select(s1 => new Room
                    {
                        BuildingNumber = s.BuildingNumber,
                        FloorNumber = s.FloorNumber,
                        RoomNumber = s.RoomNumber + s1.RoomNumber
                    }).ToList()
                }).SelectMany(m => m.Numbers).ToList();
            }
            else
            {
                buildingNumbers = floorNumbers;
            }
            buildingNumbers.ForEach(item =>
            {
                item.BuldingName = BuildingName;
                item.RoomNumber = Prefix + item.RoomNumber;
                item.RoomType = CurrentRoomType.Name;
            });
            var bn = buildingNumbers.Select(s => s.RoomNumber).ToArray();
            using (var context = new HlELockDbContext())
            {
                var oldRooms = context.Rooms.Where(w => bn.Contains(w.RoomNumber)).ToList();
                if (oldRooms.Count > 0)
                {
                    context.RemoveRange(oldRooms);
                }
                context.AddRange(buildingNumbers);
                context.SaveChanges();
                if (MyAppContext.IsSf)
                {
                    var allRooms = context.Rooms.AsNoTracking().ToList();
                    SfHelper.Instance.UpdateRoom(allRooms);
                }
            }

            EventBus.StopDialogLoading();
            MessageBox.Show(messageBoxText: "创建成功");

            System.Collections.Generic.List<Room> CreateNumber(int min, int max, string jumpString, int numberLength, Action<Room, int> action)
            {
                var rooms = new System.Collections.Generic.List<Room>();
                var jumpNumber = string.IsNullOrWhiteSpace(jumpString) ? Array.Empty<string>() : jumpString.Split(',');
                if (max == 0) return rooms;
                for (int i = min; i <= max; i++)
                {
                    if (i.ToString().Any(a => jumpNumber.Contains(a.ToString())))
                    {
                        continue;
                    }

                    var number = i.ToString();
                    if (numberLength > 1)
                    {
                        number = number.PadLeft(numberLength, '0');
                    }
                    var room = new Room
                    {
                        RoomNumber = number
                    };
                    action(room, i);
                    rooms.Add(room);
                }
                return rooms;
            }
        }

        private ObservableCollection<RoomType> _roomTypes;
        public ObservableCollection<RoomType> RoomTypes
        {
            get { return _roomTypes; }
            set { SetProperty(ref _roomTypes, value); }
        }


        private int _buildingMin;
        public int BuildingMin
        {
            get { return _buildingMin; }
            set { SetProperty(ref _buildingMin, value); }
        }

        private int _buildingMax;
        public int BuildingMax
        {
            get { return _buildingMax; }
            set { SetProperty(ref _buildingMax, value); }
        }
        private string _buildingName;
        public string BuildingName
        {
            get { return _buildingName; }
            set { SetProperty(ref _buildingName, value); }
        }
        private int _floorMin;
        public int FloorMin
        {
            get { return _floorMin; }
            set { SetProperty(ref _floorMin, value); }
        }

        private int _floorMax;
        public int FloorMax
        {
            get { return _floorMax; }
            set { SetProperty(ref _floorMax, value); }
        }

        private int _roomMin;
        public int RoomMin
        {
            get { return _roomMin; }
            set { SetProperty(ref _roomMin, value); }
        }

        private int _roomMax;
        public int RoomMax
        {
            get { return _roomMax; }
            set { SetProperty(ref _roomMax, value); }
        }

        private string _suffix;
        public string Suffix
        {
            get { return _suffix; }
            set { SetProperty(ref _suffix, value); }
        }
        private string _prefix;
        public string Prefix
        {
            get { return _prefix; }
            set { SetProperty(ref _prefix, value); }
        }

        private int _buildingLength;

        public int BuildingLength
        {
            get { return _buildingLength; }
            set { _buildingLength = value; }
        }

        private int _floorLength;
        public int FloorLength
        {
            get { return _floorLength; }
            set { _floorLength = value; }
        }

        private int _roomLength;
        public int RoomLength
        {
            get { return _roomLength; }
            set { _roomLength = value; }
        }

        private string _floorJump;
        public string FloorJump
        {
            get { return _floorJump; }
            set { SetProperty(ref _floorJump, value); }
        }
        private string _roomJump;
        public string RoomJump
        {
            get { return _roomJump; }
            set { SetProperty(ref _roomJump, value); }
        }



    }
}
